package com.example.mykotlin.service

import cn.dev33.satoken.stp.StpInterface
import com.example.mykotlin.base.auth.InitAuth
import com.example.mykotlin.base.config.cache.CacheConfig
import com.example.mykotlin.mapper.RolePermissionMapper
import com.example.mykotlin.model.entity.UserPermission
import com.example.mykotlin.model.entity.UserRole
import com.example.mykotlin.model.enums.SystemRole
import com.mybatisflex.kotlin.extensions.db.filter
import com.mybatisflex.kotlin.extensions.db.mapper
import com.mybatisflex.kotlin.extensions.kproperty.eq
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Component

@Component
class StpInterfaceImpl : StpInterface {

    @Cacheable(cacheManager = CacheConfig.REDIS_CACHE_1_HOUR, value = ["userInfo:permission"], key = "#loginId")
    override fun getPermissionList(loginId: Any?, loginType: String?): List<String>? {
        val userId = loginId.toString().toLong()
        if (InitAuth.isSystemAdminUser(userId)) return listOf("*")
        val roleList = filter<UserRole> { UserRole::userId eq loginId }
        if (roleList.map { it.roleId }.contains(SystemRole.SUPER_ADMIN.name)) return listOf("*")
        val permissionByUserId = mapper<RolePermissionMapper>().selectPermissionByUserId(userId)
        val userPermissions = filter<UserPermission> { UserPermission::userId eq loginId }
        return if (permissionByUserId.isEmpty()) {
            userPermissions.filter { !(it.isExcluded ?: false) }.map { it.permissionId ?: "" }
        } else {
            // 判断用户的角色
            val toHashSet = permissionByUserId.map { it.permissionId ?: "" }.toHashSet()
            userPermissions.forEach {
                if (it.isExcluded == true) toHashSet.remove(it.permissionId) else toHashSet.add(
                    it.permissionId ?: ""
                )
            }
            toHashSet.toList()
        }
    }

    @Cacheable(cacheManager = CacheConfig.REDIS_CACHE_1_HOUR, value = ["userInfo:role"], key = "#loginId")
    override fun getRoleList(loginId: Any?, loginType: String?): List<String> {
        val set = filter<UserRole> { UserRole::userId eq loginId }.map { it.roleId ?: "" }.toHashSet()
        if (InitAuth.isSystemAdminUser(loginId.toString().toLong())) set.add(SystemRole.SUPER_ADMIN.name)
        return set.toList()
    }

}